﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CloudStorageLight.Core.Web;
using System.Security.Principal;
using System.Collections.Generic;
using System.IO;
using System.Web.OData;
using System.Web.Http;
using CloudStorageLight.Core;

namespace CloudStorageLight.Core.Tests
{
    [TestClass]
    public class BlobODataControllerBaseTest
    {
        public class MyHttpActionResult : IHttpActionResult
        {
            public Exception Ex { get; set; }
            public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
            {
                return null;
            }
        }

        public class DataController : BlobODataControllerBase
        {
            public List<string> LogMessage = new List<string>();

            public BlobUser CurrentUser;
            protected override BlobUser GetCurrentUser()
            {
                return CurrentUser;
            }

            protected override Core.BlobService CreateBlobService()
            {
                return new CompositeBlobService();
            }

            protected override void LogError(string action, Exception ex)
            {
                LogMessage.Add(action + ex.ToString());
            }

            protected override IHttpActionResult ResponseErrorMessage(Exception ex)
            {
                return new MyHttpActionResult() { Ex = ex };
            }
        }


        public static BlobUser CreateUser(string name, bool admin)
        {
            return new BlobUser(new GenericPrincipal(new GenericIdentity(name), null)) { IsAdmin = admin };
        }

        public class CompositeBlobService : BlobService
        {
            public CompositeBlobService()
                : base(new CloudAccount("compo3"), AppUtil.GetAppConfigValue("Composit.ConnectionString"))
            {

            }

            protected override BlobContainer Container
            {
                get
                {
                    if (_container == null)
                    {
                        var list = new List<BlobAdapterBase>();

                        var spsUrl = AppUtil.GetAppConfigValue("sps.url");
                        var user = AppUtil.GetAppConfigValue("sps.user");
                        var pass = AppUtil.GetAppConfigValue("sps.pass");
                        list.Add(new SpsBlobAdapter("/SPS/", spsUrl, user, pass, "Shared Documents"));

                        var workFolder = "c:\\temp\\CompUnit2";
                        if (!Directory.Exists(workFolder)) Directory.CreateDirectory(workFolder);
                        list.Add(new FileBlobAdapter("/LOCALFILE/", workFolder + "\\"));


                        list.Add(new AzureBlobAdapter("/", "unitodata", AppUtil.GetAppConfigValue("Composit.ConnectionString")));
                        _container = new CompositeBlobContainer("unittest",
                            AppUtil.GetAppConfigValue("Composit.ConnectionString"), list);
                    }

                    return _container;
                }
            }
            private BlobContainer _container;
        }

        private static DataController CreateService()
        {
            return new DataController();
        }

        [TestMethod]
        public void フォルダ作成_コピー_フォルダ削除()
        {
            using(var helper = new CompositeBlobService())
            {

                var svc = CreateService();

                svc.CurrentUser = CreateUser("TESTUSER", true);
                var para = new ODataActionParameters();
                var result = svc.Delete("/SPS/Unit6/", para).Result;

                para.Clear();
                para.Add("directoryName", "Unit6");
                para.Add("ensure", false);
                result = svc.CreateDirectory("/SPS/", para).Result;

                var message = "テストデータ";
                var contents = System.Text.UTF8Encoding.UTF8.GetBytes(message);
                using (var st = new MemoryStream(contents))
                {
                    helper.UploadFileAsync(CreateUser("TESTUSER", true), "/SPS/Unit6/TEST.txt", st).Wait();
                    try
                    {
                        helper.CheckInAsync(CreateUser("TESTUSER", true), "/SPS/Unit6/TEST.txt").Wait();
                    }
                    catch { }
                }

                para.Clear();
                para.Add("targetId", "/LOCALFILE/TEST.txt");
                result = svc.Copy("/SPS/Unit6/TEST.txt", para).Result;
                Assert.IsFalse(result is MyHttpActionResult);

                para.Clear();
                result = svc.Checkout("/SPS/Unit6/TEST.txt", para).Result;
                Assert.IsFalse(result is MyHttpActionResult);


                //ERROR
                svc.CurrentUser = CreateUser("TESTUSER2", true);
                result = svc.Checkout("/SPS/Unit6/TEST.txt", para).Result;
                Assert.IsTrue(result is MyHttpActionResult);
                svc.CurrentUser = CreateUser("TESTUSER", true);


                message = "テストデータ2";
                contents = System.Text.UTF8Encoding.UTF8.GetBytes(message);
                using (var st = new MemoryStream(contents))
                {
                    //ERROR
                    try
                    {
                        helper.UploadFileAsync(CreateUser("TESTUSER3", true), "/SPS/Unit6/TEST.txt", st).Wait();
                        Assert.Fail();
                    }
                    catch { }
                }
                using (var st = new MemoryStream(contents))
                {
                    //OK
                    helper.UploadFileAsync(CreateUser("TESTUSER", true), "/SPS/Unit6/TEST.txt", st).Wait();
                }

                result = svc.Checkin("/SPS/Unit6/TEST.txt", para).Result;
                Assert.IsFalse(result is MyHttpActionResult);
                
                para.Add("targetId", "/TEST.txt");
                result = svc.Rename("/SPS/Unit6/TEST.txt", para).Result;
                Assert.IsFalse(result is MyHttpActionResult);

                para.Clear();
                result = svc.Delete("/TEST.txt", para).Result;
                Assert.IsFalse(result is MyHttpActionResult);
                result = svc.Delete("/LOCALFILE/TEST.txt", para).Result;
                Assert.IsFalse(result is MyHttpActionResult);
                result = svc.Delete("/SPS/Unit6/", para).Result;
                Assert.IsFalse(result is MyHttpActionResult);

            }
            
        }


    }
}
